// 《围棋》作者版权所有。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

package runtime

import "unsafe"

type mts struct {
	tv_sec  int64
	tv_nsec int64
}

type mscratch struct {
	v [6]uintptr
}

type mOS struct {
	waitsema uintptr // 用于在锁上停车的信号量
	perrno   *int32  // 指向tls errno的指针
	// 之所以在这里，是因为它们太大，无法放在低级别NOSPLIT函数的堆栈
	// 上。
	// LibCall LibCall；
	ts      mts
	scratch mscratch
}

type libcFunc uintptr

// go:linkname asmsysvicall6x runtime.asmsysvicall6 
var asmsysvicall6x libcFunc // name to take addr of asmssysvicall6 

func asmsysvicall6() // 为vet声明；不要打电话给

// go:nosplit 
func sysvicall0(fn *libcFunc) uintptr {
	// 留下来电者的PC/SP进行追踪。
	gp := getg()
	var mp *m
	if gp != nil {
		mp = gp.m
	}
	if mp != nil && mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		mp = nil // 请参阅sys_darwin中的注释。go:libcCall 
	}

	var libcall libcall
	libcall.fn = uintptr(unsafe.Pointer(fn))
	libcall.n = 0
	libcall.args = uintptr(unsafe.Pointer(fn)) // 它未使用，但必须为非零，否则崩溃
	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
	if mp != nil {
		mp.libcallsp = 0
	}
	return libcall.r1
}

// go:nosplit 
func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
	r1, _ := sysvicall1Err(fn, a1)
	return r1
}

// go:nosplit 

// sysvicall1Err返回系统调用结果和errno值。
// 这由sysvicall1和管道使用。
func sysvicall1Err(fn *libcFunc, a1 uintptr) (r1, err uintptr) {
	// 留下来电者的PC/SP进行追踪。
	gp := getg()
	var mp *m
	if gp != nil {
		mp = gp.m
	}
	if mp != nil && mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 这三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		mp = nil
	}

	var libcall libcall
	libcall.fn = uintptr(unsafe.Pointer(fn))
	libcall.n = 1
	// TODO（rsc）：为什么这里和下面都不需要scape？
	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
	if mp != nil {
		mp.libcallsp = 0
	}
	return libcall.r1, libcall.err
}

// go:nosplit 
func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
	r1, _ := sysvicall2Err(fn, a1, a2)
	return r1
}

// go:nosplit 
// go:cgo\u unsafe\u args 

// sysvicall2Err返回系统调用结果和errno值。
// 这由sysvicall2和pipe2使用。
func sysvicall2Err(fn *libcFunc, a1, a2 uintptr) (uintptr, uintptr) {
	// 留下来电者的PC/SP进行追踪。
	gp := getg()
	var mp *m
	if gp != nil {
		mp = gp.m
	}
	if mp != nil && mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 这三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		mp = nil
	}

	var libcall libcall
	libcall.fn = uintptr(unsafe.Pointer(fn))
	libcall.n = 2
	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
	if mp != nil {
		mp.libcallsp = 0
	}
	return libcall.r1, libcall.err
}

// go:nosplit 
func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
	r1, _ := sysvicall3Err(fn, a1, a2, a3)
	return r1
}

// go:nosplit 
// go:cgo\u unsafe\u args 

// sysvicall3Err返回系统调用结果和errno值。
// 这由sysicall3和write1使用。
func sysvicall3Err(fn *libcFunc, a1, a2, a3 uintptr) (r1, err uintptr) {
	// 留下来电者的PC/SP进行追踪。
	gp := getg()
	var mp *m
	if gp != nil {
		mp = gp.m
	}
	if mp != nil && mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		mp = nil
	}

	var libcall libcall
	libcall.fn = uintptr(unsafe.Pointer(fn))
	libcall.n = 3
	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
	if mp != nil {
		mp.libcallsp = 0
	}
	return libcall.r1, libcall.err
}

// go:nosplit 
func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr {
	// 将调用方的PC/sp留在周围进行回溯。
	gp := getg()
	var mp *m
	if gp != nil {
		mp = gp.m
	}
	if mp != nil && mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		mp = nil
	}

	var libcall libcall
	libcall.fn = uintptr(unsafe.Pointer(fn))
	libcall.n = 4
	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
	if mp != nil {
		mp.libcallsp = 0
	}
	return libcall.r1
}

// go:nosplit 
func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
	// 将调用者的PC/sp留下进行回溯。
	gp := getg()
	var mp *m
	if gp != nil {
		mp = gp.m
	}
	if mp != nil && mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		mp = nil
	}

	var libcall libcall
	libcall.fn = uintptr(unsafe.Pointer(fn))
	libcall.n = 5
	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
	if mp != nil {
		mp.libcallsp = 0
	}
	return libcall.r1
}

// go:nosplit 
func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
	// 将调用者的PC/sp留下进行回溯。
	gp := getg()
	var mp *m
	if gp != nil {
		mp = gp.m
	}
	if mp != nil && mp.libcallsp == 0 {
		mp.libcallg.set(gp)
		mp.libcallpc = getcallerpc()
		// sp必须是最后一个，因为一旦异步cpu探查器发现
		// 所有三个值都非零，它将使用它们
		mp.libcallsp = getcallersp()
	} else {
		mp = nil
	}

	var libcall libcall
	libcall.fn = uintptr(unsafe.Pointer(fn))
	libcall.n = 6
	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
	if mp != nil {
		mp.libcallsp = 0
	}
	return libcall.r1
}
